package com.visionork.android.twe.model;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import java.util.ArrayList;
import java.util.Date;

import android.content.Context;

import com.visionork.android.twe.TWEApplication;

public abstract class RepositoryBase implements Serializable, Crawler {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected boolean refreshFlag;
	protected Date lastUpdateTime;
	protected ArrayList<Program> programs;

	protected RepositoryBase() {
		programs = new ArrayList<Program>();
	}

	public void setPrograms(ArrayList<Program> show) {
		this.programs = show;
	}

	public Program getProgram(String key) {
		for (Program prog : programs) {
			if (prog.getKey().equals(key)) {
				return prog;
			}
		}
		return null;
	}

	public ArrayList<Program> getPrograms() {
		if (!refreshFlag && programs.size() == 0) {
			loadFromFile();
		}

		if (refreshFlag || programs.size() == 0) {
			Crawl();
			persistConfig();
		}

		if (refreshFlag = true) {
			refreshFlag = false;
		}

		return programs;
	}

	public Date getLastUpdateTime() {
		return lastUpdateTime;
	}

	public Date steLastUpdateTime(Date lastUpdateDate) {
		return this.lastUpdateTime = lastUpdateDate;
	}

	@SuppressWarnings("unchecked")
	private void loadFromFile() {
		FileInputStream fis = null;
		ObjectInputStream in = null;
		try {
			fis = TWEApplication.getAppContext().openFileInput(
					getConfigFileName());
			in = new ObjectInputStream(fis);
			Object fileObj = in.readObject();
			if (fileObj instanceof ArrayList<?>) {
				this.setPrograms((ArrayList<Program>) fileObj);
			}

			in.close();
		} catch (Exception e) {
			this.setPrograms(new ArrayList<Program>());
		}
		return;
	}

	protected void mergeProgram(ArrayList<Program> tmpPrograms) {
		for (Program prog : tmpPrograms) {
			if (!programs.contains(prog)) {
				/* add new one */
				programs.add(prog);
			} else {
				/* update old one */
				Program existProg = programs.get(programs.indexOf(prog));
				existProg.setTitle(prog.getTitle());
				existProg.setHosts(prog.getHosts());
			}
		}

		/* remove expired one */
		for (Program prog : programs) {
			if (!tmpPrograms.contains(prog)) {
				programs.remove(prog);

			}
		}
	}

	protected abstract String getConfigFileName();

	private void saveToFile() {
		if (programs != null && programs.size() > 0) {
			FileOutputStream fos = null;
			ObjectOutputStream out = null;
			try {
				fos = TWEApplication.getAppContext().openFileOutput(
						getConfigFileName(), Context.MODE_PRIVATE);

				out = new ObjectOutputStream(fos);
				out.writeObject(programs);
				out.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void persistConfig() {
		saveToFile();
	}

	public void refresh() {
		refreshFlag = true;
	}
}
